﻿using Blm.PgsqlDriver.Helpers;
using Blm.Utils.Extensions;
using ExcelReport;
using ExcelReport.Renderers;
using Language.Resource;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using Npgsql;
using System;
using System.Collections.Generic;
using System.Data;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using VisionCloud.Domain.Common;
using VisionCloud.Domain.DtoModel.Ms;
using VisionCloud.Domain.Repository.Interface.Ms;
using VisionCloud.Utility;
using VisionCloud.Utility.Option;

namespace VisionCloud.Service.Ms
{
    /// <summary>
    /// 进度分析服务类 V4.0版本
    /// </summary>
    public class ProgressAnalyzeService
    {
        public IMsProjectRepository MsProjectRepository { get; set; }

        public IProjectProgressViewRepository ProjectProgressViewRepository { set; get; }

        public IStringLocalizer<ServiceResource> Localizer { get; set; }

        private readonly UploadFileOptions uploadFileOptions;

        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="option"></param>
        public ProgressAnalyzeService(IOptionsMonitor<UploadFileOptions> option)
        {
            uploadFileOptions = option.CurrentValue;
        }

        /// <summary>
        /// 获取项目进度信息
        /// </summary>
        /// <returns></returns>
        public async Task<List<ProjectProgressAnalysisDto>> GetProjectProgressInfo(MsProjectCondition msProjectCondition)
        {
            if (msProjectCondition.ProjectStepArray == null || msProjectCondition.ProjectStepArray.Count < 1)
                throw new ArgumentException(Localizer["YB0197"].Value);

            #region 总体进度

            string sql = string.Empty;
            List<ProjectProgressAnalysisDto> projectProgressAnalysisDtos = new List<ProjectProgressAnalysisDto>();
            List<NpgsqlParameter> parameters = new List<NpgsqlParameter>();

            #region 项目信息

            if (OperatorProvider.Get().RoleNameList == "公司管理员")
            {
                sql = "select t1.\"ProjectId\", t1.\"ProjectNo\", t1.\"Name\" as \"ProjectName\", t1.\"Details\", t2.\"ProjectTotalArea\" " +
                         " from \"MsProject\" t1 " +
                         " left join( select md.\"ProjectId\" , sum(m.\"MapArea\") as \"ProjectTotalArea\" from \"MsHouseMapDetails\" md left join \"MsHouseMap\" m on m.\"HouseMapId\" = md.\"HouseMapId\" " +
                         "WHERE md.\"IsDeleted\" = FALSE group by md.\"ProjectId\") t2 " +
                         " on t1.\"ProjectId\" = t2.\"ProjectId\" " +
                         " where t1.\"IsDeleted\" = false and t1.\"CompanyGuid\" = @CompanyGuid and \"PubliceDate\" is not null ";
            }
            else
            {
                sql = "select t1.\"ProjectId\", t1.\"ProjectNo\", t1.\"Name\" as \"ProjectName\", t1.\"Details\", t3.\"ProjectTotalArea\" " +
                    " from \"MsProject\" t1 join \"MsUserToProject\" t2 on t2.\"YunProjectGuid\" = t1.\"ProjectId\" " +
                    " left join( select md.\"ProjectId\" , sum(m.\"MapArea\") as \"ProjectTotalArea\" from \"MsHouseMapDetails\" md left join \"MsHouseMap\" m on m.\"HouseMapId\" = md.\"HouseMapId\" " +
                    "WHERE md.\"IsDeleted\" = FALSE group by md.\"ProjectId\") t3 " +
                    " on t3.\"ProjectId\" = t1.\"ProjectId\" " +
                    " where t1.\"IsDeleted\" = false and t1.\"CompanyGuid\" = @CompanyGuid and t2.\"YunUserGuid\" = @YunUserGuid and \"PubliceDate\" is not null";
            }

            parameters.Add(new NpgsqlParameter("@CompanyGuid", OperatorProvider.Get().CompanyGuid));
            parameters.Add(new NpgsqlParameter("@YunUserGuid", OperatorProvider.Get().YunUserGuid));

            if (msProjectCondition.ProjectId != Guid.Empty)
            {
                sql += " and t1.\"ProjectId\" = @ProjectId ";
                parameters.Add(new NpgsqlParameter("@ProjectId", msProjectCondition.ProjectId));
            }
            if (!string.IsNullOrEmpty(msProjectCondition.ProjectName))
            {
                sql += " and t1.\"Name\" like @ProjectName ";
                parameters.Add(new NpgsqlParameter("@ProjectName", "%" + msProjectCondition.ProjectName.Replace("%", @"\%").Replace("_", @"\_") + "%"));
            }

            var progressInfoDtos = await PgSqlHelper.QueryListAsync<ProjectProgressInfoDto>(sql, parameters.ToArray());
            foreach (var item in progressInfoDtos)
            {
                ProjectProgressAnalysisDto projectProgressAnalysisDto = new ProjectProgressAnalysisDto
                {
                    ProjectId = item.ProjectId,
                    ProjectNo = item.ProjectNo,
                    ProjectName = item.ProjectName,
                    ProjectMeasureSteps = msProjectCondition.ProjectStepArray ?? new List<ProjectMeasureStepEnum>(),
                    TaskTypeCount = msProjectCondition.TaskTypeArray?.Count > 0 ? msProjectCondition.TaskTypeArray.Count : 2,
                    TotalArea = item.ProjectTotalArea ?? 0
                };
                if (item.Details.IsNotNull())
                {
                    var details = item.Details.ToObject<List<DetailProgress>>();
                    projectProgressAnalysisDto.DetailInfo = details.OrderBy(p => p.Building.ToInt()).ToList();
                }
                projectProgressAnalysisDtos.Add(projectProgressAnalysisDto);
            }

            #endregion 项目信息

            if (projectProgressAnalysisDtos.Count > 0)
            {
                #region 测量数据初始化

                List<Guid> projectIds = projectProgressAnalysisDtos.Select(x => x.ProjectId).ToList();
                var statisQuery = ProjectProgressViewRepository.SelectProgressList(projectIds, msProjectCondition.TaskTypeArray);
                var list = statisQuery.ToList();
                statisQuery.ToList()?.ForEach(s =>
                {
                    var statis = s.CopyTo<BuildingInfo>();
                    statis.FloorNum = s.FloorNum.ToInt();
                    statis.TaskType = s.TaskType;
                    statis.TaskProperty = s.TaskProperty;
                    var curPrj = projectProgressAnalysisDtos.Where(p => p.ProjectId == statis.ProjectId).FirstOrDefault();
                    if (curPrj != null)
                    {
                        curPrj.SetStatisToBuildingInfos(statis);
                    }
                });

                #endregion 测量数据初始化
            }

            #endregion 总体进度

            return projectProgressAnalysisDtos;
        }

        /// <summary>
        /// 项目进度导出到excel
        /// </summary>
        /// <param name="msProjectCondition">项目ID,楼栋</param>
        /// <returns></returns>
        public async Task<List<BuildingInfo>> GetProjectProgress(MsProjectCondition msProjectCondition)
        {
            var projectProgressAnalysisDtos = await GetProjectProgressInfo(msProjectCondition);
            if (projectProgressAnalysisDtos != null && projectProgressAnalysisDtos.Count > 0)
            {
                return projectProgressAnalysisDtos[0].BuildingInfos;
            }
            else
            {
                return new List<BuildingInfo>();
            }
        }

        /// <summary>
        /// 分页获取项目进度列表
        /// </summary>
        /// <param name="condition"></param>
        /// <returns></returns>
        public async Task<PagerDto> GetProjectProgressPageInfo(MsProjectCondition condition)
        {
            var projectProgressAnalysisDtos = await GetProjectProgressInfo(condition);
            PagerDto pagerDto = new PagerDto();
            pagerDto.PageIndex = condition.CurrentPage;  // 前端初始分页页码为1
            pagerDto.PageSize = condition.PageSize;
            pagerDto.Total = projectProgressAnalysisDtos.Count;
            pagerDto.Result = projectProgressAnalysisDtos.OrderByDescending(p => p.SumPercent).Skip((condition.CurrentPage - 1) * condition.PageSize).Take(condition.PageSize);
            return pagerDto;
        }

        /// <summary>
        /// 获取项目进度详情
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentException"></exception>
        /// <exception cref="OperationException"></exception>
        public async Task<ProgressAnalysisDetailResponse> GetProjectProgressDetail(ProjectProgressDetailRequestDto request)
        {
            if (request.ProjectStepArray?.Count < 1) throw new ArgumentException(Localizer["YB0197"].Value);
            if (!request.ProjectId.IsNotNull()) throw new ArgumentException(Localizer["YB0198"].Value);
            var project = await MsProjectRepository.FirstOrDefaultAsync(x => x.ProjectId == request.ProjectId);
            if (project == null) throw new OperationException(Localizer["YB0199"].Value);
            var buildList = JsonConvert.DeserializeObject<List<BuildingDetail>>(project.Details);
            buildList.Sort((x, y) => x.Floor.ToInt() - y.Floor.ToInt());
            var build = buildList.Where(x => (request.BuildingName.IsNullOrWhiteSpace() || x.Building == request.BuildingName)).FirstOrDefault();
            if (build == null) throw new OperationException(Localizer["YB0200"].Value);
            ProgressAnalysisDetailResponse responseDto = new ProgressAnalysisDetailResponse()
            {
                TotalFloors = build.Floor.ToInt(),
                CompletedInfos = new List<CompletedInfo>()
            };
            var list = await ProjectProgressViewRepository.GetProgressInfos(request.ProjectId, request.BuildingName, request.Type);
            request.ProjectStepArray.ForEach(step =>
            {
                List<int> floors = new List<int>();
                switch (step)
                {
                    case ProjectMeasureStepEnum.结构初测:
                        floors = list.Where(x => x.StructuralFirstDateTime.HasValue).Select(x => x.FloorNum.ToInt32()).ToList();
                        break;
                    case ProjectMeasureStepEnum.结构复测:
                        floors = list.Where(x => x.StructuralSecondDateTime.HasValue).Select(x => x.FloorNum.ToInt32()).ToList();
                        break;
                    case ProjectMeasureStepEnum.砌筑初测:
                        floors = list.Where(x => x.MasonryFirstDateTime.HasValue).Select(x => x.FloorNum.ToInt32()).ToList();
                        break;
                    case ProjectMeasureStepEnum.砌筑复测:
                        floors = list.Where(x => x.MasonrySecondDateTime.HasValue).Select(x => x.FloorNum.ToInt32()).ToList();
                        break;
                    case ProjectMeasureStepEnum.抹灰初测:
                        floors = list.Where(x => x.PlasterFirstDateTime.HasValue).Select(x => x.FloorNum.ToInt32()).ToList();
                        break;
                    case ProjectMeasureStepEnum.抹灰复测:
                        floors = list.Where(x => x.PlasterSecondDateTime.HasValue).Select(x => x.FloorNum.ToInt32()).ToList();
                        break;
                    case ProjectMeasureStepEnum.装饰初测:
                        floors = list.Where(x => x.DecorateFirstDateTime.HasValue).Select(x => x.FloorNum.ToInt32()).ToList();
                        break;
                    case ProjectMeasureStepEnum.装饰复测:
                        floors = list.Where(x => x.DecorateSecondDateTime.HasValue).Select(x => x.FloorNum.ToInt32()).ToList();
                        break;
                    default:
                        break;
                }
                responseDto.CompletedInfos.Add(new CompletedInfo(step.ToInt32(), floors));
            });
            return responseDto;
        }

        /// <summary>
        /// 项目进度导出到excel
        /// </summary>
        /// <param name="msProjectCondition">项目ID,楼栋</param>
        /// <returns></returns>
        public async Task<string> ExportProgressToExcelFile(MsProjectCondition msProjectCondition)
        {
            var projectProgressAnalysisDtos = await GetProjectProgressInfo(msProjectCondition);
            return BuildProgressExcel(projectProgressAnalysisDtos);
        }

        /// <summary>
        /// 创建进度分析Excel，返回相对于wwwroot的路径
        /// </summary>
        /// <returns></returns>
        private string BuildProgressExcel(List<ProjectProgressAnalysisDto> projectProgressAnalysisDtos)
        {
            var excelPath = Path.Combine(uploadFileOptions.ParentDir, uploadFileOptions.TemporaryFiles);
            if (!Directory.Exists(excelPath)) Directory.CreateDirectory(excelPath);
            var lang = CultureInfo.CurrentUICulture.Name;
            var tempFile = $"progress-template-{lang}-v2.xlsx";
            var templatePath = Path.Combine(uploadFileOptions.ParentDir, "SystemFiles", "ExcelTemplates", tempFile);

            // 准备进度信息数据
            if (projectProgressAnalysisDtos.Count < 1) throw new OperationException(Localizer["YB0063"].Value);
            var progressInfo = projectProgressAnalysisDtos[0];
            string dateStr = DateTime.Now.ToDateTimeStandardString();

            // 月度统计 第一期只统计总数
            List<YearMonthStatis> yearMonthStatis = new List<YearMonthStatis>();
            YearMonthStatis monthStatis = new YearMonthStatis
            {
                YearMonth = Localizer["YB0455"].Value,
                StructFirstTimeMeasuredArea = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.结构初测.ToString()).FirstOrDefault()?.MeasuredArea.ToString(),
                StructSecondTimeMeasuredArea = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.结构复测.ToString()).FirstOrDefault()?.MeasuredArea.ToString(),
                MasonryFirstTimeMeasuredArea = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.砌筑初测.ToString()).FirstOrDefault()?.MeasuredArea.ToString(),
                MasonrySecondTimeMeasuredArea = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.砌筑复测.ToString()).FirstOrDefault()?.MeasuredArea.ToString(),
                PlasterFirstTimeMeasuredArea = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.抹灰初测.ToString()).FirstOrDefault()?.MeasuredArea.ToString(),
                PlasterSecondTimeMeasuredArea = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.抹灰复测.ToString()).FirstOrDefault()?.MeasuredArea.ToString(),
                DecorateFirstTimeMeasuredArea = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.装饰初测.ToString()).FirstOrDefault()?.MeasuredArea.ToString(),
                DecorateSecondTimeMeasuredArea = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.装饰复测.ToString()).FirstOrDefault()?.MeasuredArea.ToString(),
                SumArea = Math.Round(progressInfo.MeasuredAreaSum, 2, MidpointRounding.AwayFromZero).ToString(),

                StructFirstTimeMeasuredPercent = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.结构初测.ToString()).FirstOrDefault()?.MeasuredPercent.ToString(),
                StructSecondTimeMeasuredPercent = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.结构复测.ToString()).FirstOrDefault()?.MeasuredPercent.ToString(),
                MasonryFirstTimeMeasuredPercent = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.砌筑初测.ToString()).FirstOrDefault()?.MeasuredPercent.ToString(),
                MasonrySecondTimeMeasuredPercent = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.砌筑复测.ToString()).FirstOrDefault()?.MeasuredPercent.ToString(),
                PlasterFirstTimeMeasuredPercent = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.抹灰初测.ToString()).FirstOrDefault()?.MeasuredPercent.ToString(),
                PlasterSecondTimeMeasuredPercent = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.抹灰复测.ToString()).FirstOrDefault()?.MeasuredPercent.ToString(),
                DecorateFirstTimeMeasuredPercent = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.装饰初测.ToString()).FirstOrDefault()?.MeasuredPercent.ToString(),
                DecorateSecondTimeMeasuredPercent = progressInfo.MeasureStepDetails.Where(x => x.MeasureStep == ProjectMeasureStepEnum.装饰复测.ToString()).FirstOrDefault()?.MeasuredPercent.ToString(),
                SumPercent = progressInfo.SumPercent.ToString()
            };
            yearMonthStatis.Add(monthStatis);

            // 已测层数
            List<MeasuredFloor> measuredFloors = new List<MeasuredFloor>();
            foreach (var detail in progressInfo.DetailInfo)
            {
                MeasuredFloor measuredFloor = new MeasuredFloor
                {
                    Building = detail.Building,
                    FloorNumCount = detail.Floor,
                    StructuralFirstDateTimeCount = detail.FloorStructFirstTime.Count.ToString(),
                    StructuralSecondDateTimeCount = detail.FloorStructSecondTime.Count.ToString(),
                    MasonryFirstDateTimeCount = detail.FloorMasonryFirstDateTime.Count.ToString(),
                    MasonrySecondeDateTimeCount = detail.FloorMasonrySecondDateTime.Count.ToString(),
                    PlasterFirstDateTimeCount = detail.FloorPlasterFirstDateTime.Count.ToString(),
                    PlasterSecondDateTimeCount = detail.FloorPlasterSecondDateTime.Count.ToString(),
                    DecorateFirstDateTimeCount = detail.FloorDecorateFirstDateTime.Count.ToString(),
                    DecorateSecondDateTimeCount = detail.FloorDecorateSecondDateTime.Count.ToString()
                };
                measuredFloors.Add(measuredFloor);
            }

            // 进度详情
            List<ProgressDetail> progressDetails = new List<ProgressDetail>();
            if (progressInfo.BuildingInfos == null)
            {
                progressInfo.BuildingInfos = new List<BuildingInfo>();
            }
            foreach (var info in progressInfo.BuildingInfos)
            {
                ProgressDetail progressDetail = new ProgressDetail
                {
                    Building = info.BuildingName,
                    FloorNum = info.FloorNum.ToString(),
                    StructuralFirstDateTime = info.StructuralFirstDateTime?.ToDateStandardString(),
                    StructuralSecondDateTime = info.StructuralSecondDateTime?.ToDateStandardString(),
                    MasonryFirstDateTime = info.MasonryFirstDateTime?.ToDateStandardString(),
                    MasonrySecondDateTime = info.MasonrySecondDateTime?.ToDateStandardString(),
                    PlasterFirstDateTime = info.PlasterFirstDateTime?.ToDateStandardString(),
                    PlasterSecondDateTime = info.PlasterSecondDateTime?.ToDateStandardString(),
                    DecorateFirstDateTime = info.DecorateFirstDateTime?.ToDateStandardString(),
                    DecorateSecondDateTime = info.DecorateSecondDateTime?.ToDateStandardString(),
                    MapArea = info.MapArea.ToString()
                };

                progressDetails.Add(progressDetail);
            }

            #region 生成EXCEL

            Configurator.Put(".xlsx", new ExcelReport.Driver.NPOI.WorkbookLoader());
            try
            {
                excelPath = Path.Combine(excelPath, projectProgressAnalysisDtos[0].ProjectName + Localizer["YB0453"].Value + DateTime.Now.ToString("yyyyMMddHHmmssfff") + $"_{StatisService.GetRandomNumber()}.xlsx");
                ExportHelper.ExportToLocal(templatePath, excelPath,
                        new SheetRenderer(Localizer["YB0452"].Value,
                        new ParameterRenderer("ProjectNo", progressInfo.ProjectNo),
                        new ParameterRenderer("ProjectName", progressInfo.ProjectName),
                        new ParameterRenderer("StatisDate", dateStr),
                            new RepeaterRenderer<YearMonthStatis>("Roster", yearMonthStatis,
                                new ParameterRenderer<YearMonthStatis>("YearMonth", t => t.YearMonth),
                                new ParameterRenderer<YearMonthStatis>("StructFirstTimeMeasuredArea", t => t.StructFirstTimeMeasuredArea),
                                new ParameterRenderer<YearMonthStatis>("StructSecondTimeMeasuredArea", t => t.StructSecondTimeMeasuredArea),
                                new ParameterRenderer<YearMonthStatis>("MasonryFirstTimeMeasuredArea", t => t.MasonryFirstTimeMeasuredArea),
                                new ParameterRenderer<YearMonthStatis>("MasonrySecondTimeMeasuredArea", t => t.MasonrySecondTimeMeasuredArea),
                                new ParameterRenderer<YearMonthStatis>("PlasterFirstTimeMeasuredArea", t => t.PlasterFirstTimeMeasuredArea),
                                new ParameterRenderer<YearMonthStatis>("PlasterSecondTimeMeasuredArea", t => t.PlasterSecondTimeMeasuredArea),
                                new ParameterRenderer<YearMonthStatis>("DecorateFirstTimeMeasuredArea", t => t.DecorateFirstTimeMeasuredArea),
                                new ParameterRenderer<YearMonthStatis>("DecorateSecondTimeMeasuredArea", t => t.DecorateSecondTimeMeasuredArea),
                                new ParameterRenderer<YearMonthStatis>("SumArea", t => t.SumArea),
                                new ParameterRenderer<YearMonthStatis>("StructFirstTimeMeasuredPercent", t => t.StructFirstTimeMeasuredPercent
                                + (string.IsNullOrWhiteSpace(t.StructFirstTimeMeasuredPercent) ? "" : "%")),
                                new ParameterRenderer<YearMonthStatis>("StructSecondTimeMeasuredPercent", t => t.StructSecondTimeMeasuredPercent
                                + (string.IsNullOrWhiteSpace(t.StructSecondTimeMeasuredPercent) ? "" : "%")),
                                new ParameterRenderer<YearMonthStatis>("MasonryFirstTimeMeasuredPercent", t => t.MasonryFirstTimeMeasuredPercent
                                + (string.IsNullOrWhiteSpace(t.MasonryFirstTimeMeasuredPercent) ? "" : "%")),
                                new ParameterRenderer<YearMonthStatis>("MasonrySecondTimeMeasuredPercent", t => t.MasonrySecondTimeMeasuredPercent
                                + (string.IsNullOrWhiteSpace(t.MasonrySecondTimeMeasuredPercent) ? "" : "%")),
                                new ParameterRenderer<YearMonthStatis>("PlasterFirstTimeMeasuredPercent", t => t.PlasterFirstTimeMeasuredPercent
                                + (string.IsNullOrWhiteSpace(t.PlasterFirstTimeMeasuredPercent) ? "" : "%")),
                                new ParameterRenderer<YearMonthStatis>("PlasterSecondTimeMeasuredPercent", t => t.PlasterSecondTimeMeasuredPercent
                                + (string.IsNullOrWhiteSpace(t.PlasterSecondTimeMeasuredPercent) ? "" : "%")),
                                new ParameterRenderer<YearMonthStatis>("DecorateFirstTimeMeasuredPercent", t => t.DecorateFirstTimeMeasuredPercent
                                + (string.IsNullOrWhiteSpace(t.DecorateFirstTimeMeasuredPercent) ? "" : "%")),
                                new ParameterRenderer<YearMonthStatis>("DecorateSecondTimeMeasuredPercent", t => t.DecorateSecondTimeMeasuredPercent
                                + (string.IsNullOrWhiteSpace(t.DecorateSecondTimeMeasuredPercent) ? "" : "%")),
                                new ParameterRenderer<YearMonthStatis>("SumPercent", t => t.SumPercent
                                + (string.IsNullOrWhiteSpace(t.SumPercent) ? "" : "%"))
                                )
                            ),

                        new SheetRenderer(Localizer["YB0454"].Value,
                        new ParameterRenderer("ProjectNo", progressInfo.ProjectNo),
                        new ParameterRenderer("ProjectName", progressInfo.ProjectName),
                        new ParameterRenderer("StatisDate", dateStr),
                            new RepeaterRenderer<MeasuredFloor>("Roster", measuredFloors,
                                new ParameterRenderer<MeasuredFloor>("Building", t => t.Building),
                                new ParameterRenderer<MeasuredFloor>("FloorNumCount", t => t.FloorNumCount),
                                new ParameterRenderer<MeasuredFloor>("StructuralFirstDateTimeCount", t => t.StructuralFirstDateTimeCount),
                                new ParameterRenderer<MeasuredFloor>("StructuralSecondDateTimeCount", t => t.StructuralSecondDateTimeCount),
                                new ParameterRenderer<MeasuredFloor>("MasonryFirstDateTimeCount", t => t.MasonryFirstDateTimeCount),
                                new ParameterRenderer<MeasuredFloor>("MasonrySecondeDateTimeCount", t => t.MasonrySecondeDateTimeCount),
                                new ParameterRenderer<MeasuredFloor>("PlasterFirstDateTimeCount", t => t.PlasterFirstDateTimeCount),
                                new ParameterRenderer<MeasuredFloor>("PlasterSecondDateTimeCount", t => t.PlasterSecondDateTimeCount),
                                new ParameterRenderer<MeasuredFloor>("DecorateFirstDateTimeCount", t => t.DecorateFirstDateTimeCount),
                                new ParameterRenderer<MeasuredFloor>("DecorateSecondDateTimeCount", t => t.DecorateSecondDateTimeCount)
                                )
                            ),
                        new SheetRenderer(Localizer["YB0453"].Value,
                        new ParameterRenderer("ProjectNo", progressInfo.ProjectNo),
                        new ParameterRenderer("ProjectName", progressInfo.ProjectName),
                        new ParameterRenderer("StatisDate", dateStr),
                            new RepeaterRenderer<ProgressDetail>("Roster", progressDetails.OrderBy(p => p.Building.ToInt32()).ThenBy(p => p.FloorNum.ToInt32()).ToList(),
                                new ParameterRenderer<ProgressDetail>("Building", t => t.Building),
                                new ParameterRenderer<ProgressDetail>("FloorNum", t => t.FloorNum),
                                new ParameterRenderer<ProgressDetail>("StructuralFirstDateTime", t => t.StructuralFirstDateTime),
                                new ParameterRenderer<ProgressDetail>("StructuralSecondDateTime", t => t.StructuralSecondDateTime),
                                new ParameterRenderer<ProgressDetail>("MasonryFirstDateTime", t => t.MasonryFirstDateTime),
                                new ParameterRenderer<ProgressDetail>("MasonrySecondDateTime", t => t.MasonrySecondDateTime),
                                new ParameterRenderer<ProgressDetail>("PlasterFirstDateTime", t => t.PlasterFirstDateTime),
                                new ParameterRenderer<ProgressDetail>("PlasterSecondDateTime", t => t.PlasterSecondDateTime),
                                new ParameterRenderer<ProgressDetail>("DecorateFirstDateTime", t => t.DecorateFirstDateTime),
                                new ParameterRenderer<ProgressDetail>("DecorateSecondDateTime", t => t.DecorateSecondDateTime),
                                new ParameterRenderer<ProgressDetail>("MapArea", t => t.MapArea)
                                )
                            )
                        );
            }
            catch (Exception e)
            {
                Logger.Error("生成进度Excel异常", e);
            }

            #endregion 生成EXCEL

            return excelPath.Substring(uploadFileOptions.ParentDir.Length);
        }
    }
}
